package rpc.client;


import rpc.intf.RpcClient;
import rpc.packet.RpcRequest;
import rpc.packet.RpcResponse;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;

//完成代理类要做的功能(调用目标方法，功能增强)
public class RpcClientProxy implements InvocationHandler {

    private RpcClient rpcClient;

    public RpcClientProxy(RpcClient rpcClient) {
        this.rpcClient = rpcClient;
    }


    /**
     * 获取目标对象的代理类对象
     * @param clazz
     * @param <T>
     * @return
     */
    public <T> T getProxy(Class<T> clazz) {
        /**
         * ClassLoader 被代理类的类加载器
         * Class<?>[] 获取被代理类实现的所有接口
         * InvocationHandler 为一个InvocationHandler实现对象，实现扩展功能
         */
        return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class<?>[]{clazz}, this);
    }

    /**
     * 代理对象要执行的功能代码
     * @param proxy jdk创建的对象，无需提供
     * @param method 目标类中的方法
     * @param args 目标类中的方法参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        RpcRequest rpcRequest = RpcRequest.builder()
                .interfaceName(method.getDeclaringClass().getName())
                .methodName(method.getName())
                .parameters(args)
                .requestId(UUID.randomUUID().toString())
                .paramTypes(method.getParameterTypes())
                .build();

        CompletableFuture<RpcResponse> completableFuture = (CompletableFuture<RpcResponse>) rpcClient.sendRequest(rpcRequest);
        //等待结果返回
        RpcResponse rpcResponse = completableFuture.get();

        //返回数据前，做个检查

        return rpcResponse.getData();
    }
}
